package com.miku.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miku.blog.domain.*;
import com.miku.blog.domain.dto.UserInfoDTO;
import com.miku.blog.domain.pojo.LoginUser;
import com.miku.blog.domain.pojo.ResponseResult;
import com.miku.blog.domain.pojo.SystemConstance;
import com.miku.blog.domain.vo.UserVo;
import com.miku.blog.eume.HttpStatusEnum;
import com.miku.blog.exception.SystemException;
import com.miku.blog.service.RoleService;
import com.miku.blog.service.UserInfoService;
import com.miku.blog.mapper.UserInfoMapper;
import com.miku.blog.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
* @author Miku
* @description 针对表【tb_user_info】的数据库操作Service实现
* @createDate 2022-05-25 23:09:23
*/
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
    implements UserInfoService{

    @Autowired
    private RoleService roleService;
    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseResult updateInfo(UserInfoDTO userInfoDTO) {

        String nickname = userInfoDTO.getNickname();
        String avatar = userInfoDTO.getAvatar();

        if (!StringUtils.hasText(nickname)
                || !StringUtils.hasText(avatar)
        ){
            return new ResponseResult(HttpStatusEnum.PARAM_ERROR);
        }

        LoginUser loginUser = SecurityUtils.getLoginUser();
        UserInfo info = loginUser.getUserInfo();

        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getNickname,nickname);
        UserInfo one = getOne(queryWrapper);
        if (Objects.nonNull(one)){
            if (!info.getNickname().equals(one.getNickname())) {
                return new ResponseResult(HttpStatusEnum.NICKNAME_IS_ALREADY_EXIST);
            }
        }

        UserInfo userInfo = BeanCopyUtils.copyObjectByType(userInfoDTO, UserInfo.class);

        LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserInfo::getUserId,loginUser.getUserAuth().getId());
        if (!update(userInfo,updateWrapper)) {
            return new ResponseResult(HttpStatusEnum.UPDATE_DATA_ERROR);
        }

        String intro = userInfo.getIntro();
        String webSite = userInfo.getWebSite();

        info.setNickname(nickname)
                .setAvatar(avatar);
        if (StringUtils.hasText(intro)){
            info.setIntro(intro);
        }
        if (StringUtils.hasText(webSite)){
            info.setWebSite(webSite);
        }
        updateRedisCacheUser(loginUser);

        return ResponseResult.ok();
    }


//    @Override
//    public UserInfo getUserInfoByUserIdAndNickName(Integer userId, String nickName){
//
//        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(UserInfo::getUserId,userId)
//                .like(StringUtils.hasText(nickName),UserInfo::getNickname,nickName);
//        return getOne(queryWrapper);
//    }

    @Override
    public List<UserInfo> getAllUserInfoListByNickName(String nickName){
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(nickName),UserInfo::getNickname,nickName)
                .orderByDesc(UserInfo::getCreateTime);
        return list(queryWrapper);
    }

    @Override
    public UserInfo getUserInfoByUserId(Integer userId){
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getUserId,userId)
                .eq(UserInfo::getIsDisable,SystemConstance.NOT_DISABLE);

        return getOne(queryWrapper);
    }


    @Override
    public Page<UserInfo> getUserInfoListByLikeNickName(Integer current, Integer size, String nickName){

        Page<UserInfo> page = new Page<>(current, size);
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(nickName),UserInfo::getNickname,nickName)
                    .orderByDesc(UserInfo::getCreateTime);
        page(page,queryWrapper);
        return page;
    }


    @Override
    public boolean disableByUserId(Integer userId,Integer isDisable){

        LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserInfo::getUserId,userId)
                .set(UserInfo::getIsDisable,isDisable)
                .set(UserInfo::getUpdateTime,new Date());
        return update(updateWrapper);
    }


    @Override
    public boolean updateNickNameByUserId(Integer userId,String nickName){
        if (!StringUtils.hasText(nickName)) {
            throw new SystemException(HttpStatusEnum.PARAM_ERROR);
        }
        LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserInfo::getUserId,userId)
                .set(UserInfo::getNickname,nickName)
                .set(UserInfo::getUpdateTime,new Date());
        return update(updateWrapper);
    }


    @Transactional
    @Override
    public ResponseResult updateNickNameAndRole(UserVo userVo) {

        Integer userId = userVo.getId();
        String nickname = userVo.getNickname();
        if (Objects.isNull(userId) || !StringUtils.hasText(nickname)){
            return new ResponseResult(HttpStatusEnum.PARAM_ERROR);
        }

        List<Integer> roleIdList = userVo.getRoleIdList();
        if (Objects.nonNull(roleIdList) && roleIdList.size() > 1) {
            return new ResponseResult(HttpStatusEnum.UPDATE_ROLE_ERROR);
        }


        if (!updateNickNameByUserId(userId,nickname)) {
            return new ResponseResult(HttpStatusEnum.UPDATE_DATA_ERROR);
        }

        /**
         * 此处已做 Redis同步处理
         */
        roleService.updateRole(roleIdList,userId);

        return ResponseResult.ok();
    }


    private void updateRedisCacheUser(LoginUser loginUser){
        String redisCacheKey = GenerateKeyUtils.generateRedisCacheKey(HttpUtils.getHttpServletRequest(), null);
        redisCache.setCacheObject(redisCacheKey,
                loginUser,
                SystemConstance.REDIS_EXPIRE_TIME,
                SystemConstance.REDIS_TIMEUNIT);

        redisCache.setCacheObject(GenerateKeyUtils.getRedisUserCacheKey(loginUser.getUserAuth().getId()),
                redisCacheKey,
                SystemConstance.REDIS_ID_KEY_EXPIRE_TIME,
                SystemConstance.REDIS_TIMEUNIT);
    }
}




